package com.cristina.attention.utils;

import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 将多张图片划分为九宫格形式
 * 10 > picture > 1
 *
 * @author by superman
 */
@Slf4j
public class PictureSudokuUtil {

    /**
     * 第一个 %s 是项目路径
     * 第二个 %s 是用户id
     * 第三个 %s 是群id
     * %s/PictureSudoku/%s/%s/
     */
    private final String routeRule = "%s%sPictureSudoku%s%s%s%s%s%s.png";

    private final String PNG_SUFFIX = "png";

    private final String HTTP_PREFIX = "https://";
    private final String HTTPS_PREFIX = "http://";
    /**
     * 图片宽度
     */
    private final Integer PIC_WIDTH = 422;
    /**
     * 图片高度
     */
    private final Integer PIC_HEIGHT = 422;
    /**
     * 空白宽度
     */
    private final Integer PIC_SPACE = 14;

    /**
     * 小图片宽度
     */
    private Double LUMP_WIDTH = null;
    /**
     * 小图片起始点横坐标
     */
    private Double LUMP_POINT_X = null;
    /**
     * 小图片起始点纵坐标
     */
    private Double LUMP_POINT_Y = null;

    /***
     *  2 和 4 的区别  向下偏移量          0.5 LUMP_WIDTH+  0.5 PIC_SPACE
     *  3 和 4 的区别 第一张图向右偏移量   0.5 LUMP_WIDTH + 0.5 PIC_SPACE
     *  5 和 6 的区别 第一张图向右偏移量   0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     *  6 和 9 的区别 向下偏移量          0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     *  7 和 9 的区别 第一张图向右偏移量  LUMP_WIDTH+PIC_SPACE
     *  8 和 9 的区别 第一张图向右偏移量  0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     */

    /**
     * 围边使用的灰色
     */
    private final int[] COLOR_GREY_BGR = new int[]{230, 230, 230};

    /**
     * 校对数组使用下标
     */
    private int flg = 0;

    /**
     * 合成图片
     *
     * @param pics     图片 list
     * @param path     存储路径
     * @param fileName 文件名
     * @return
     */
    public String getCombinationOfHead(List<String> pics, String path, String fileName, String ownerId, String groupId) {
        List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();

        // BufferedImage.TYPE_INT_RGB可以自己定义可查看API
        BufferedImage outImage = new BufferedImage(PIC_WIDTH, PIC_HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D gra = outImage.createGraphics();

        // 设置背景为蓝灰色
        gra.setColor(toColor(COLOR_GREY_BGR));

        // 填满图片
        gra.fillRect(0, 0, PIC_WIDTH, PIC_HEIGHT);

        // 开始拼凑 根据图片的数量判断该生成哪种样式组合头像

        // 图片数量
        Integer size = pics.size();

        // 宽度  一行几张图片
        Integer sqrt = (int) Math.ceil(Math.sqrt(size));
        LUMP_WIDTH = (PIC_WIDTH - ((sqrt + 1.0) * PIC_SPACE)) / sqrt;

        // 压缩图片所有的图片生成尺寸同意的 为 125*125
        for (int i = 0; i < pics.size(); i++) {
            BufferedImage resize2 = resize2(pics.get(i), LUMP_WIDTH.intValue(), LUMP_WIDTH.intValue(), true);
            bufferedImages.add(resize2);
        }

        //缺几个满伍
        int lack = 0;
        //计算起始点坐标
        if (size < sqrt * (sqrt - 1)) {
            // 少一行 不满5
            //缺几个满伍
            lack = sqrt * (sqrt - 1) - size;
            //向右边偏移量
            LUMP_POINT_X = PIC_SPACE.doubleValue() + lack * (LUMP_WIDTH + PIC_SPACE) / 2;
            //向下偏移量
            LUMP_POINT_Y = PIC_SPACE.doubleValue() + LUMP_WIDTH / 2.;
        } else if (size == sqrt * (sqrt - 1)) {
            // 满5少一行
            //向右边偏移量
            LUMP_POINT_X = PIC_SPACE.doubleValue();
            //向下偏移量
            LUMP_POINT_Y = PIC_SPACE.doubleValue() + LUMP_WIDTH / 2.;
        } else if (size < sqrt * sqrt) {
            // 不满5
            //缺几个满5
            lack = sqrt * sqrt - size;
            //向右边偏移量
            LUMP_POINT_X = PIC_SPACE.doubleValue() + lack * (LUMP_WIDTH + PIC_SPACE) / 2;
            LUMP_POINT_Y = PIC_SPACE.doubleValue();
        } else if (size == sqrt * sqrt) {
            // 满5
            LUMP_POINT_X = PIC_SPACE.doubleValue();
            LUMP_POINT_Y = PIC_SPACE.doubleValue();
        }

        // 第几行图片
        int line = lack == 0 ? -1 : 0;
        // 第几列图片
        int row = 0;
        for (int i = 0; i < bufferedImages.size(); i++) {
            if ((i + lack) % sqrt == 0) {
                line++;
                row = 0;
            }
            if (line == 0) {
                gra.drawImage(bufferedImages.get(i), LUMP_POINT_X.intValue() + (row++ * (PIC_SPACE + LUMP_WIDTH.intValue()))
                        , LUMP_POINT_Y.intValue(), null);
            } else {
                gra.drawImage(bufferedImages.get(i), PIC_SPACE + (row++ * (PIC_SPACE + LUMP_WIDTH.intValue()))
                        , LUMP_POINT_Y.intValue() + (line * (PIC_SPACE + LUMP_WIDTH.intValue())), null);
            }
        }

        String completePath = getCompletePath(fileName, ownerId, groupId);
        File file = new File(completePath);
        //文件如果存在先删除，再创建
        try {
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
                if (file.exists()) {
                    file.delete();
                    if (!file.createNewFile()) {
                        log.error("创建失败");
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        //将图片写到文件
        try {
            boolean write = ImageIO.write(outImage, PNG_SUFFIX, file);
            if (!write) {
                return null;
            }
            return completePath;
            // completePath
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 图片缩放
     *
     * @param picPath 本地或网络图片路径
     * @param height 缩放后高度
     * @param width 缩放后宽度
     * @param fill 是否填充灰色
     * @return
     */
    public BufferedImage resize2(String picPath, Integer height, Integer width, boolean fill) {
        try {
            BufferedImage imageBuff = null;
            // 简单判断是网络图片还是本地图片
            if (picPath.indexOf(HTTPS_PREFIX) == 0 || picPath.indexOf(HTTP_PREFIX) == 0) {
                imageBuff = ImageIO.read(new URL(picPath));
            } else {
                imageBuff = ImageIO.read(new File(picPath));
            }
            Image iTemp = imageBuff.getScaledInstance(width, height, Image.SCALE_SMOOTH);

            // 缩放比例
            double ratio = 0;
            // 计算比例
            if ((imageBuff.getHeight() > height) || (imageBuff.getWidth() > width)) {
                if (imageBuff.getHeight() > imageBuff.getWidth()) {
                    ratio = height.doubleValue() / imageBuff.getHeight();
                } else {
                    ratio = width.doubleValue() / imageBuff.getWidth();
                }
                AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);

                iTemp = op.filter(imageBuff, null);
            }
            if (fill) {
                BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

                Graphics2D g = image.createGraphics();

                g.setColor(toColor(COLOR_GREY_BGR));

                g.fillRect(0, 0, width, height);

                if (width == iTemp.getWidth(null))
                    g.drawImage(iTemp, 0, (height - iTemp.getHeight(null)) / 2,
                            iTemp.getWidth(null), iTemp.getHeight(null),
                            Color.white, null);
                else
                    g.drawImage(iTemp, (width - iTemp.getWidth(null)) / 2, 0,
                            iTemp.getWidth(null), iTemp.getHeight(null),
                            Color.white, null);
                g.dispose();
                iTemp = image;
            }
            return (BufferedImage) iTemp;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * @toColor 颜色索引转为颜色
     * @param colorRoot 颜色索引
     * @return 颜色
     */
    private Color toColor(int[] colorRoot) {
        if (colorRoot.length >= 3) {
            return new Color(colorRoot[0], colorRoot[1], colorRoot[2]);
        } else {
            return null;
        }
    }

    private String getCompletePath(String fileName, String ownerId, String groupId) {
        String userDir = OsUtil.getUserDir();
        String separator = OsUtil.getFileSeparator();
        // 哪个用户 哪个群
        String path = String.format(routeRule, userDir, separator, separator, ownerId, separator, groupId, separator, fileName);
        if (OsUtil.isBackSlant()) {
            path = path.replaceAll("\\\\", "\\\\\\\\");
        }
        return path;
    }
}
